package avicit.bdp.dgs.mdm.service;

import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.dgs.mdm.dao.TopicDAO;
import avicit.bdp.dgs.mdm.dto.TopicDTO;
import avicit.bdp.dgs.mdm.utils.constants.Constants;
import avicit.bdp.dgs.mdm.utils.enums.EnableState;
import avicit.platform6.api.system.ConvertColumnClient;
import avicit.platform6.api.system.impl.SystemConstant;
import avicit.platform6.commons.utils.BusinessUtil;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.rest.msg.QueryRespBean;
import com.github.pagehelper.Page;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @金航数码科技有限责任公司
 * @作者：developer
 * @邮箱：developer@avic-digital.com
 * @创建时间： 2023-12-04
 * @类说明：TopicService
 * @修改记录：
 * @注意事项：
 * @主要功能：主题Service
 */
@Service
public class TopicService extends BaseService<TopicDAO, TopicDTO> {
    private static final Logger logger = LoggerFactory.getLogger(TopicService.class);

    @Autowired
    private TopicDAO topicDAO;

    @Autowired
    private ConvertColumnClient convertColumnClient;

    /**
     * 新增主题
     *
     * @param topicDTO
     * @return
     */
    @Transactional
    public String addTopic(TopicDTO topicDTO) {
        checkAddValidity(topicDTO);

        return saveTopic2Db(topicDTO);
    }

    /**
     * 删除/批量删除主题，多个id使用英文逗号隔开
     *
     * @param id
     * @return
     */
    @Transactional
    public int deleteTopic(String id) {
        if (StringUtils.isBlank(id)) {
            return 0;
        }

//        long cnt = this.mapper.checkBeforeDelete(id);
//        return this.topicDAO.deleteTopicByCond(Arrays.asList(id.trim().split(Constants.COMMA)));
        return deleteTopicInner(id);
    }

    /**
     * 修改主题
     *
     * @param topicDTO
     * @return
     */
    @Transactional
    public boolean updateTopic(TopicDTO topicDTO) {
        checkUpdateValidity(topicDTO);

        updateTopic2Db(topicDTO);

        return true;
    }

    /**
     * 查询主题详情
     *
     * @param id 主题ID
     * @return
     */
    public TopicDTO getTopicDetail(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }

        TopicDTO queryRet = this.selectByPrimaryKey(id);
        if (queryRet == null) {
            throw new BusinessException("未找到主题，id：" + id);
        }

        valueConvert(Arrays.asList(queryRet));

        return queryRet;
    }

    /**
     * 分页查询主题
     *
     * @param keyWords
     * @param code
     * @param status
     * @param pageNo
     * @param pageSize
     * @return
     */
    public QueryRespBean<TopicDTO> queryTopic(String keyWords, String code, Integer status, Integer pageNo, Integer pageSize) {
        QueryRespBean<TopicDTO> queryRespBean = new QueryRespBean<>();

        com.github.pagehelper.PageHelper.startPage(pageNo, pageSize);
        Page<TopicDTO> queryRet = this.mapper.queryTopicByCond(keyWords, code, status);
        queryRespBean.setResult(queryRet);

        valueConvert(queryRet.getResult());

        return queryRespBean;
    }

    /**
     * 获取主题树
     *
     * @param keyWords
     * @param code
     * @return
     */
    public List<TopicDTO> queryTopicTree(String keyWords, String code) {
        List<TopicDTO> queryRet = this.mapper.getTopicListByCond(1, keyWords, code);
        if (CollectionUtils.isEmpty(queryRet)) {
            return new ArrayList<>();
        }

        valueConvert(queryRet);

        TopicDTO rootNode = new TopicDTO();
        rootNode.setId("-1");
        rootNode.setName("主题分类");
        rootNode.setCode("root");
        rootNode.setChildren(queryRet);

        return Arrays.asList(rootNode);
    }

    /**
     * 获取主题列表
     * 注意：
     * 1、数据维护模块使用，仅可查询启用状态的主题 && 已绑定模型的主题列表 && 模型表已发布的主题，否则未发布的模型会导致查询报错
     *
     * @param keyWords
     * @param code
     * @return
     */
    public List<TopicDTO> getTopicList(String keyWords, String code) {
        List<TopicDTO> queryRet = this.mapper.getTopicListByModelStatus(1, keyWords, code);
        if (CollectionUtils.isEmpty(queryRet)) {
            return new ArrayList<>();
        }

        valueConvert(queryRet);

        TopicDTO rootNode = new TopicDTO();
        rootNode.setId("-1");
        rootNode.setName("主题分类");
        rootNode.setCode("root");
        rootNode.setChildren(queryRet);

        return Arrays.asList(rootNode);
    }

    /**
     * 查询未使用的主题列表
     *
     * @param type     模型类型，0：普通模型
     * @param keyWords 主题名称
     * @param code     主题编码
     * @return
     */
    public List<TopicDTO> getUnusedTopicList(Integer type, String keyWords, String code) {
        if (type == null) {
            type = 0;
        }

        return this.mapper.getUnusedTopicList(type, keyWords, code);
    }

    /**
     * 主题名称或编码是否重复
     *
     * @param topicId 主题ID，编辑时修改名称，需要传入topicId;新增场景不需要传入
     * @param name    主题名称
     * @param code    主题编码
     * @return
     */
    public boolean isSameName(String topicId, String name, String code) {
        long count = this.mapper.selectNameCount(topicId, name, code);
        if (count > 0) {
            return true;
        }

        return false;
    }

    /**
     * 启用停用
     *
     * @param id
     * @param status
     * @return
     */
    @Transactional
    public boolean updateStatus(String id, Integer status) {
        if (StringUtils.isEmpty(id)) {
            throw new BusinessException("主题ID为空");
        }
        if (status == null) {
            throw new BusinessException("状态为空");
        }

        TopicDTO topicDTO = this.selectByPrimaryKey(id);
        if (topicDTO == null) {
            throw new BusinessException("未找到主题，id:" + id);
        }

        topicDTO.setStatus(status);
        this.updateByPrimaryKeySelective(topicDTO);

        return true;
    }

    /**
     * 统计主题总量
     *
     * @return
     */
    public long countTopic() {
        return this.mapper.countTopic();
    }

    /**
     * 新增合法性检查
     *
     * @param topicDTO
     */
    private void checkAddValidity(TopicDTO topicDTO) {
        if (topicDTO == null) {
            throw new BusinessException("入参为null");
        }

        if (StringUtils.isEmpty(topicDTO.getName())) {
            throw new BusinessException("主题名称为空");
        }

        if (StringUtils.isEmpty(topicDTO.getCode())) {
            throw new BusinessException("主题编码为空");
        }
    }

    /**
     * 修改合法性检查
     *
     * @param topicDTO
     */
    private void checkUpdateValidity(TopicDTO topicDTO) {
        if (topicDTO == null) {
            throw new BusinessException("入参为null");
        }

        if (StringUtils.isEmpty(topicDTO.getId())) {
            throw new BusinessException("主键ID为空");
        }

        if (StringUtils.isEmpty(topicDTO.getName())) {
            throw new BusinessException("主题名称为空");
        }

        if (StringUtils.isEmpty(topicDTO.getCode())) {
            throw new BusinessException("主题编码为空");
        }
    }

    /**
     * 主题持久化到Db
     *
     * @param topicDTO
     * @return
     */
    private String saveTopic2Db(TopicDTO topicDTO) {
        if (topicDTO == null) {
            return null;
        }

        topicDTO.setId(ComUtil.getId());
        topicDTO.setStatus(EnableState.DISABLE.getCode());
        this.insert(topicDTO);

        BdpLogUtil.log4Insert(topicDTO);

        return topicDTO.getId();
    }

    /**
     * 主题持久化到Db
     *
     * @param topicDTO
     * @return
     */
    private String updateTopic2Db(TopicDTO topicDTO) {
        if (topicDTO == null) {
            return null;
        }

        TopicDTO oldDTO = this.topicDAO.selectByPrimaryKey(topicDTO.getId());
        if (oldDTO == null) {
            throw new BusinessException("未找到主题，id：" + topicDTO.getId());
        }

        this.updateByPrimaryKeySelective(topicDTO);

        BdpLogUtil.log4Update(topicDTO, oldDTO);

        return topicDTO.getId();
    }

    /**
     * 删除主题
     * 1、如果有模型关联主题，则不能删除主题
     *
     * @param id
     * @return
     */
    private int deleteTopicInner(String id) {
        List<String> errTopicNameList = new ArrayList<>();
        List<String> toBeDeletedTopicIdList = new ArrayList<>();
        List<String> topicIdList = Arrays.asList(id.trim().split(Constants.COMMA));
        if (CollectionUtils.isEmpty(topicIdList)) {
            return 0;
        }

        for (String topicId : topicIdList) {
            if (StringUtils.isEmpty(topicId)) {
                continue;
            }

            TopicDTO topicDTO = this.getTopicDetail(topicId);
            long cnt = this.mapper.checkBeforeDelete(topicId);
            if (cnt > 0) {
                errTopicNameList.add(topicDTO.getName());
            } else {
                toBeDeletedTopicIdList.add(topicId);
            }
        }

        // 删除模型
        int deletedNum = 0;
        if (CollectionUtils.isNotEmpty(toBeDeletedTopicIdList)) {
            deletedNum = this.topicDAO.deleteTopicByCond(toBeDeletedTopicIdList);
        }

        // 返回异常信息或已删除主题数量
        if (CollectionUtils.isNotEmpty(errTopicNameList)) {
            throw new BusinessException(String.format("主题【%s】已关联主数据模型，无法删除，请删除关联的模型！", String.join(Constants.COMMA, errTopicNameList)));
        } else {
            return deletedNum;
        }
    }

    /**
     * 通过平台API将字段值转换为名称，包括通用选择组件、通用代码
     *
     * @param dtoList
     */
    private void valueConvert(List<TopicDTO> dtoList) {
        if (CollectionUtils.isEmpty(dtoList)) {
            return;
        }

        // 设置创建者名称
        Map<String, Set<String>> convertFormData = new HashMap<>();
        for (TopicDTO dto : dtoList) {
            BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, dto.getCreatedBy());
        }
        if (convertFormData.size() > 0) {
            //获取请求结果
            Map<String, Map<String, String>> convertResultData = convertColumnClient.replace(convertFormData);
            //循环设置Alias或Name的值
            for (TopicDTO dto : dtoList) {
                dto.setUserName(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER, dto.getCreatedBy()));
                dto.setCreatedBy(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER, dto.getCreatedBy()));
            }
        }

        // 设置枚举值
        for (TopicDTO dto : dtoList) {
            if (dto.getStatus() != null) {
                dto.setStatusName(EnableState.getDescByCode(dto.getStatus()));
            }
        }
    }
}
